<template>
  <!-- 自定义轮播 -->
  <div class="carousel" :style="sizeStyle">
    <div :style="scrollStyle" v-for="(item,index) in list" :key="index">
      <a :href="item.url">
        <img
          :src="item.path"
          :alt="item.title"
          :style="sizeStyle"
          :class="(currentIndex==index+1)?'selected':'unSelect'"
        />
      </a>
      <span v-if="showTitle" class="title">{{item.title}}</span>
    </div>
    <!-- 过渡图片 -->
    <div :style="scrollStyle">
      <a :href="firstItem.url">
        <img
          :src="firstItem.path"
          :alt="firstItem.title"
          :style="sizeStyle"
          :class="(currentIndex==1)?'selected':'unSelect'"
        />
      </a>
      <span v-if="showTitle" class="title">{{firstItem.title}}</span>
    </div>
    <!-- 指示控件 -->
    <div class="dotList">
      <span @click="handleSwitch(index)" class="dot" v-for="(item,index) in list" :key="item.title">
        <div v-show="currentIndex==index+1" class="dot-actived"></div>
      </span>
    </div>
  </div>
</template>

<script>
let timer;
let transtionTimer;
export default {
  name: "Carousel",
  props: {
    list: {
      type: Array,
      required: true,
      default() {
        return [];
      }
    },
    showTitle: {
      type: Boolean,
      default() {
        return true;
      }
    }
  },
  data() {
    return {
      width: 300,
      height: 200,
      currentIndex: 1,
      scrollStyle: { transform: "translateX(0px)" }
    };
  },
  mounted() {
    this.begin();
  },
  computed: {
    firstItem() {
      return this.list[0];
    },
    number() {
      return this.list.length + 1;
    },
    sizeStyle() {
      return { width: this.width + "px", height: this.height + "px" };
    }
  },
  methods: {
    begin() {
      timer = setInterval(() => {
        if (transtionTimer) {
          return;
        }
        this.scroll();
      }, 2000);
    },
    scroll() {
      let start = -(((this.currentIndex - 1) % this.number) * this.width);
      let end = -(this.currentIndex % this.number) * this.width;
      if (end == 0) {
        start = 0;
        end = -this.width;
      }
      this.move(start, end);
    },
    move(start, end) {
      let offset = this.width / 20;
      //定时器，实现平移效果
      transtionTimer = setInterval(() => {
        start = start - offset;
        if (start <= end) {
          clearInterval(transtionTimer);
          transtionTimer = null;
          start = end;
          if (this.currentIndex % this.number == 0) {
            this.currentIndex = 1;
          } else {
            this.currentIndex++;
            // 过渡效果：移动到最后一张图后（我们在最后加的第一张图片），把偏移量设置为0，自动切换成第一图
            if (this.currentIndex == this.number) {
              this.currentIndex = 1;
              start = 0;
            }
          }
        }
        this.scrollStyle = {
          transform: "translateX(" + start + "px)"
        };
      }, 20);
    },
    handleSwitch(index) {
      clearInterval(transtionTimer);
      transtionTimer = null;
      clearInterval(timer);
      timer = null;
      this.currentIndex = index + 1;

      this.scrollStyle = {
        transform: "translateX(" + -(index % this.number) * this.width + "px)",
        transition: "opacity 0.6s linear"
      };
      this.begin();
    }
  },
  destroyed() {
    clearInterval(timer);
    timer = null;
    clearInterval(transtionTimer);
    transtionTimer = null;
  }
};
</script>

<style lang="less" scoped>
.carousel {
  display: flex;
  overflow: hidden;
  position: relative;
  margin: 0 auto;
  width: 100%;
  height: 100%;
}

/* 动画效果 */
.selected {
  opacity: 1;
  animation: myOpacity 0.6s;
}
.unSelect {
  opacity: 0.1;
}

@keyframes myOpacity {
  0% {
    opacity: 0.1;
  }
  25% {
    opacity: 0.25;
  }
  50% {
    opacity: 0.5;
  }
  75% {
    opacity: 0.75;
  }
  100% {
    opacity: 1;
  }
}

.dotList {
  display: flex;
  position: absolute;
  z-index: 1000;
  right: 20px;
  bottom: 40px;
}
.dot {
  width: 10px;
  height: 10px;
  margin: 0 2px;
  background: #fff;
  border-radius: 50%;
  display: flex;
  cursor: pointer;
}

.dot-actived {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: orange;
}

.title {
  height: 30px;
  background: rgba(213, 213, 230, 0.4);
  text-align: center;
  position: absolute;
  transform: translateY(-100%);
  color: #fff;
  display: flex;
  width: 100%;
  justify-content: center;
}
</style>